// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf

#ifndef MGCSTREAM_H
#define MGCSTREAM_H

#include "MgcRTLib.h"
#include "MgcSmartPointer.h"
#include "MgcTArray.h"
#include "MgcTClassArray.h"
#include "MgcTClassMap.h"
#include "MgcTMap.h"
MgcSmartPointer(MgcObject);


class MgcStream
{
public:
    // construction and destruction
    MgcStream ();
    ~MgcStream ();

    // The objects to process, each object representing an entry into a
    // connected component of the abstract graph.
    bool Insert (MgcObject* pkTopLevel);
    void RemoveAll ();
    unsigned int GetObjectCount ();
    MgcObject* GetObjectAt (unsigned int uiIndex) const;
    bool IsTopLevel (MgcObject* pkObject);

    // file loads and saves
    bool Load (const char* acFilename);
    bool Save (const char* acFilename);

    // memory loads and saves
    bool Load (char* acBuffer, int iSize);
    bool Save (char*& racBuffer, int& riSize);

    // load/save support
    bool InsertInMap (MgcObject* pkKey, void* pvValue);
    MgcObject* GetFromMap (MgcObject* pkLinkID);
    FILE* GetFile ();
    void ReadString (char*& racString);
    void WriteString (const char* acString);

    // linking support
    class Link
    {
    public:
        Link (MgcObject* pkObject);

        MgcObject* GetObject ();

        unsigned int GetQuantity () const;
        MgcObject* GetLinkID ();

        enum { LINK_GROW_BY = 8 };
        void Add (MgcObject* pkLinkID);

    protected:
        MgcObject* m_pkObject;
        unsigned int m_uiQuantity, m_uiCurrent;
        MgcTArray<MgcObject*> m_akLinkID;
    };

protected:
    // version string always of form "Magic3D Version x.yy" (21 characters)
    enum { VERSION_STRING_LENGTH = 21 };
    static const char ms_acVersion[VERSION_STRING_LENGTH];

    // top level object storage
    static const unsigned int ms_uiTopLevelGrowBy;
    MgcTClassArray<MgcObjectPtr> m_aspkTopLevel;

    // input/output file
    FILE* m_pkFile;

    // registration of objects on Save
    MgcTMap<MgcObject*,void*> m_kMap;
};

#include "MgcStream.inl"
#include "MgcStream.mcr"

#endif
